/*
ID: icerupt1
PROG: job
LANG: C++11
*/

/* solution
 *
 * great problem.
 * 过A机器比较显然，只要贪心就好，不断维护一个优先队列就好。
 * 过B的话想不到可以二分答案。
 *
 * 其实，B反过来和A是一样的。同样也求出一个第k个产品需要的最短时间，反过来，
 * 和A的对应第k个相加求最大值就是答案了。
 *
*/

#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

std::ifstream fin {"job.in" };
std::ofstream fout{"job.out"};

struct task { int time; int cost; };

bool operator<(task a, task b)
{
	return a.time > b.time || (a.time == b.time && a.cost > b.cost);
}

int n, ma, mb;
std::priority_queue<task, std::vector<task>> task_a;
std::vector<int> task_a_end;
std::priority_queue<task, std::vector<task>> task_b;
std::vector<int> task_b_end;

int main()
{
	fin >> n >> ma >> mb;
	for (int i = 0, t; i < ma; i++) {
		fin >> t;
		task_a.push({0, t});
	}
	for (int i = 0, t; i < mb; i++) {
		fin >> t;
		task_b.push({0, t});
	}

	int count_a = 0, min_a, count_b = 0, min_b = 0;
	for (; count_a < n; ) {
		task tmp = task_a.top();
		task_a.pop();
		if (tmp.time) {
			count_a++;
			task_a_end.push_back(tmp.time);
			if (count_a == n) min_a = tmp.time;
		}
		task_a.push({tmp.time + tmp.cost, tmp.cost});
	}

	for (; count_b < n; ) {
		task tmp = task_b.top();
		task_b.pop();
		if (tmp.time) {
			count_b++;
			task_b_end.push_back(tmp.time);
		}
		task_b.push({tmp.time + tmp.cost, tmp.cost});
	}

	std::reverse(task_b_end.begin(), task_b_end.end());

	for (int i = 0; i < n; i++)
		min_b = std::max(min_b, task_a_end[i] + task_b_end[i]);

	std::cout << min_a << ' ' << min_b << '\n';
	fout << min_a << ' ' << min_b << '\n';
}
